package lxs.swift.tool;

import org.jetbrains.annotations.NotNull;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Objects;
import java.util.function.Supplier;

public class NoCreator {
    private volatile int serialInSameKey = 0;
    private volatile Object lastKey = null;
    private final String prefix;

    private NoCreator(String prefix) {
        this.prefix = prefix;
    }

    public String get() {
        long ms = System.currentTimeMillis();
        int serial = this.getSerialInSameKey(ms);
        return this.prefix + ms + "." + serial;
    }

    public static NoCreator ms(String prefix) {
        return new NoCreator(prefix);
    }

    public static NoCreator key(String prefix, @NotNull Supplier<String> keySupply) {
        return new KeyNoCreator(prefix, keySupply);
    }

    protected synchronized int getSerialInSameKey(Object key) {
        if (Objects.equals(key, this.lastKey)) {
            this.serialInSameKey++;
        } else {
            this.lastKey = key;
            this.serialInSameKey = 0;
        }
        return this.serialInSameKey;
    }

    public static final class KeyNoCreator extends NoCreator {
        private final Supplier<String> keySupply;

        public KeyNoCreator(String prefix, @NotNull Supplier<String> keySupply) {
            super(prefix);
            this.keySupply = keySupply;
        }

        public synchronized String get() {
            String key = keySupply.get();
            int serial = super.getSerialInSameKey(key);
            return super.prefix + key + "." + serial;
        }
    }

//    public static void main(String[] args) {
//        NoCreator wd = NoCreator.key("WD", () -> {
//            DateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
//            return sdf.format(new Date());
//        });
//        for (int i = 0; i < 100; i++) {
//            String s = wd.get();
//            System.out.println(s);
//        }
//    }
}
